
import unittest
import diabind
import testdata
import os

class SymTypeTest( unittest.TestCase ):

    def __get_glob(self):
        if not hasattr(self, "__glob"):
            self.__glob = testdata.loaded_session.get_globalScope()
        return self.__glob

    def __get_udt(self, name):
        enum_syms = self.__get_glob().findChildren( diabind.SymTagUDT,
                                                    name,
                                                    diabind.nsfCaseSensitive )
        self.assertEqual(len(enum_syms), 1)
        return enum_syms[0]

    def __get_data(self, name):
        enum_syms = self.__get_glob().findChildren( diabind.SymTagData,
                                                    name,
                                                    diabind.nsfCaseSensitive )
        self.assertEqual(len(enum_syms), 1)
        return enum_syms[0]

    def __get_enum(self, name):
        if not hasattr(self, "__enum"):
            glob = testdata.loaded_session.get_globalScope()
            enum = self.__get_glob().findChildren( diabind.SymTagEnum,
                                                   name,
                                                   diabind.nsfUndecoratedName )
            self.assertEqual(len(enum), 1)
            self.__enum = enum[0]
        return self.__enum

    def test_length(self):
        sym = self.__get_data("CDiaErrorTranslate::g_pType").get_type().get_type()
        enum_syms = sym.findChildren(diabind.SymTagNull, "ob_refcnt", diabind.nsfCaseSensitive)
        self.assertEqual(len(enum_syms), 1)
        self.assertTrue(enum_syms[0].get_type().get_length() >= 4)
        self.assertTrue(enum_syms[0].get_type().get_length() <= sym.get_length())

    def test_offset(self):
        sym = self.__get_data("CDiaErrorTranslate::g_pType").get_type().get_type()
        enum_syms = sym.findChildren(diabind.SymTagNull, "ob_refcnt", diabind.nsfCaseSensitive)
        self.assertEqual(len(enum_syms), 1)
        self.assertTrue(enum_syms[0].get_offset() >= 0)

    def test_volatileType(self):
        sym = self.__get_data("CDiaErrorTranslate::g_pType").get_type()
        self.assertFalse(sym.get_volatileType())

    def test_access(self):
        sym = self.__get_data("CDiaErrorTranslate::g_pType").get_type().get_type()
        enum_syms = sym.findChildren(diabind.SymTagNull, "ob_refcnt", diabind.nsfCaseSensitive)
        self.assertEqual(len(enum_syms), 1)
        self.assertEqual(enum_syms[0].get_access(), diabind.CV_public)

    def test_value(self):
        self.assertTrue(diabind.UndecorateFlag_Complete != diabind.UndecorateFlag_NoThistype)
        self.assertTrue(diabind.UndecorateFlag_NoThistype != diabind.UndecorateFlag_NoArguments)

        sym = self.__get_enum("diabind::UndecorateFlag")
        values = [ enum_entry.get_value() for enum_entry in sym.findChildren(diabind.SymTagNull, "", diabind.nsNone ) ]
        self.assertTrue(diabind.UndecorateFlag_Complete in values)
        self.assertTrue(diabind.UndecorateFlag_NoThistype in values)
        self.assertTrue(diabind.UndecorateFlag_NoArguments in values)
